package com.sweet.collection;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * 集合工具
 *
 * @author limi
 * @version 2015-10-15
 */
public final class CollectionUtil {
    private CollectionUtil() {
    }

    /**
     * 判断指定集合是否为null或空集合
     *
     * @param collection
     * @return
     */
    public static boolean isEmpty(Collection<?> collection) {
        return CollectionUtils.isEmpty(collection);
    }

    /**
     * 判断指定集合是否不为null或有集合元素
     *
     * @param collection
     * @return
     */
    public static boolean isNotEmpty(Collection<?> collection) {
        return !isEmpty(collection);
    }

    /**
     * 判断指定Map是否为null或空集合
     *
     * @param map
     * @return
     */
    public static boolean isEmpty(Map<?, ?> map) {
        return MapUtils.isEmpty(map);
    }

    /**
     * 判断指定Map是否不为null或包含集合元素
     *
     * @param map
     * @return
     */
    public static boolean isNotEmpty(Map<?, ?> map) {
        return !isEmpty(map);
    }

    /**
     * 将集合转为字符串
     *
     * @param datas
     * @param separator
     * @return
     */
    public static String join(Collection<?> datas, String separator) {
        return StringUtils.join(datas, separator);
    }

    /**
     * 获取两个集合的并集
     *
     * @param one
     * @param two
     * @return
     */
    public static Collection<?> union(Collection<?> one, Collection<?> two) {
        return CollectionUtils.union(one, two);
    }

    /**
     * 获取两个集合的交集
     *
     * @param one
     * @param two
     * @return
     */
    public static Collection<?> intersection(Collection<?> one, Collection<?> two) {
        return CollectionUtils.intersection(one, two);
    }

    /**
     * 获取两个集合的差集
     *
     * @param one
     * @param two
     * @return
     */
    public static Collection<?> disjunction(Collection<?> one, Collection<?> two) {
        return CollectionUtils.disjunction(one, two);
    }

    /**
     * 集合转为list
     *
     * @param coll
     * @param <T>
     * @return
     */
    public static <T> List<T> convertToList(Collection<T> coll) {
        List<T> list;
        if (coll instanceof List) {
            list = (List) coll;
        } else {
            list = new ArrayList(coll);
        }

        return list;
    }

    /**
     * 集合转为set
     *
     * @param coll
     * @param <T>
     * @return
     */
    public static <T> Set<T> convertToSet(Collection<T> coll) {
        Set<T> set;
        if (coll instanceof Set) {
            set = (Set) coll;
        } else {
            set = new HashSet(coll);
        }

        return set;
    }

    /**
     * 获取最大值
     * 支持byte、short、int、long、float、double
     *
     * @param coll
     * @param <T>
     * @return
     */
    public static <T extends Number & Comparable<T>> T getMax(Collection<T> coll) {
        if (isEmpty(coll)) {
            throw new IllegalArgumentException("数据为空");
        }

        T max = null;
        for (T num : coll) {
            if (max == null || num.compareTo(max) > 0) {
                max = num;
            }
        }
        return max;
    }

    /**
     * 获取最小值
     * 支持byte、short、int、long、float、double
     *
     * @param coll
     * @param <T>
     * @return
     */
    public static <T extends Number & Comparable<T>> T getMin(Collection<T> coll) {
        if (isEmpty(coll)) {
            throw new IllegalArgumentException("数据为空");
        }

        T min = null;
        for (T num : coll) {
            if (min == null || num.compareTo(min) < 0) {
                min = num;
            }
        }
        return min;
    }

    /**
     * 获取平均值
     * 支持byte、short、int、long、float、double
     *
     * @param coll
     * @param <T>
     * @return
     */
    public static <T extends Number> double getAverage(Collection<T> coll) {
        if (isEmpty(coll)) {
            throw new IllegalArgumentException("数据为空");
        }

        double sum = 0;
        for (T num : coll) {
            sum += num.doubleValue();
        }
        return sum / coll.size();
    }
}